home *** CD-ROM | disk | FTP | other *** search
/ PCGUIA 127 / PC Guia 127.iso / Software / Utils / GParted Live CD / Bin / gparted-livecd-0.2.2.iso / usr_sqfs / bin / kibitz < prev    next >
Encoding:
Text File  |  2005-07-18  |  10.5 KB  |  411 lines

  1. #!/bin/sh
  2. # \
  3. exec expect -- "$0" ${1+"$@"}
  4. # allow another user to share a shell (or other program) with you
  5. # See kibitz(1) man page for complete info.
  6. # Author: Don Libes, NIST
  7. # Date written: December 5, 1991
  8. # Date last editted: October 19, 1994
  9. # Version: 2.11
  10. exp_version -exit 5.0
  11.  
  12. # if environment variable "EXPECT_PROMPT" exists, it is taken as a regular
  13. # expression which matches the end of your login prompt (but does not other-
  14. # wise occur while logging in).
  15.  
  16. set prompt "(%|#|\\$) $"    ;# default prompt
  17. set noproc 0
  18. set tty ""            ;# default if no -tty flag
  19. set allow_escape 1        ;# allow escapes if true
  20. set escape_char \035        ;# control-right-bracket
  21. set escape_printable "^\]"
  22. set verbose 1            ;# if true, describe what kibitz is doing
  23.  
  24. set kibitz "kibitz"        ;# where kibitz lives if some unusual place.
  25.                 ;# this must end in "kibitz", but can have
  26.                 ;# things in front (like directory names).
  27. #set proxy "kibitz"        ;# uncomment and set if you want kibitz to use
  28.                 ;# some other account on remote systems
  29.  
  30. # The following code attempts to intuit whether cat buffers by default.
  31. # The -u flag is required on HPUX (8 and 9) and IBM AIX (3.2) systems.
  32. if {[file exists $exp_exec_library/cat-buffers]} {
  33.     set catflags "-u"
  34. } else {
  35.     set catflags ""
  36. }
  37. # If this fails, you can also force it by commenting in one of the following.
  38. # Or, you can use the -catu flag to the script.
  39. #set catflags ""
  40. #set catflags "-u"
  41.  
  42. # Some flags must be passed onto the remote kibitz process.  They are stored
  43. # in "kibitz_flags".  Currently, they include -tty and -silent.
  44. set kibitz_flags ""
  45.  
  46. while {[llength $argv]>0} {
  47.     set flag [lindex $argv 0]
  48.     switch -- $flag \
  49.     "-noproc" {
  50.         set noproc 1
  51.         set argv [lrange $argv 1 end]
  52.     } "-catu" {
  53.         set catflags "-u"
  54.         set argv [lrange $argv 1 end]
  55.     } "-tty" {
  56.         set tty [lindex $argv 1]
  57.         set argv [lrange $argv 2 end]
  58.         set kibitz_flags "$kibitz_flags -tty $tty"
  59.     } "-noescape" {
  60.         set allow_escape 0
  61.         set argv [lrange $argv 1 end]
  62.     } "-escape" {
  63.         set escape_char [lindex $argv 1]
  64.         set escape_printable $escape_char
  65.         set argv [lrange $argv 2 end]
  66.     } "-silent" {
  67.         set verbose 0
  68.         set argv [lrange $argv 1 end]
  69.         set kibitz_flags "$kibitz_flags -silent"
  70.     } "-proxy" {
  71.         set proxy [lindex $argv 1]
  72.         set argv [lrange $argv 2 end]
  73.     } default {
  74.         break
  75.     }
  76. }
  77.  
  78. if {([llength $argv]<1) && ($noproc==0)} {
  79.     send_user "usage: kibitz \[args] user \[program ...]\n"
  80.     send_user "   or: kibitz \[args] user@host \[program ...]\n"
  81.     exit
  82. }
  83.  
  84. log_user 0
  85. set timeout -1
  86.  
  87. set user [lindex $argv 0]
  88. if {[string match -r $user]} {
  89.     send_user "KRUN"    ;# this tells user_number 1 that we're running
  90.                 ;# and to prepare for possible error messages
  91.     set user_number 3
  92.     # need to check that it exists first!
  93.     set user [lindex $argv 1]
  94. } else {
  95.     set user_number [expr 1+(0==[string first - $user])]
  96. }
  97.  
  98. # at this point, user_number and user are correctly determined
  99. # User who originated kibitz session has user_number == 1 on local machine.
  100. # User who is responding to kibitz has user_number == 2.
  101. # User who originated kibitz session has user_number == 3 on remote machine.
  102.  
  103. # user 1 invokes kibitz as "kibitz user[@host]"
  104. # user 2 invokes kibitz as "kibitz -####" (some pid).
  105. # user 3 invokes kibitz as "kibitz -r user".
  106.  
  107. # uncomment for debugging: leaves each user's session in a file: 1, 2 or 3
  108. #exec rm -f $user_number
  109. #exp_internal -f $user_number 0
  110.  
  111. set user2_islocal 1    ;# assume local at first
  112.  
  113. # later move inside following if $user_number == 1
  114. # return true if x is a prefix of xjunk, given that prefixes are only
  115. # valid at . delimiters
  116. # if !do_if0, skip the whole thing - this is here just to make caller simpler
  117. proc is_prefix {do_if0 x xjunk} {
  118.     if 0!=$do_if0 {return 0}
  119.     set split [split $xjunk .]
  120.     for {set i [expr [llength $split]-1]} {$i>=0} {incr i -1} {
  121.         if {[string match $x [join [lrange $split 0 $i] .]]} {return 1}
  122.     }
  123.     return 0
  124. }
  125.  
  126. # get domainname.  Unfortunately, on some systems, domainname(1)
  127. # returns NIS domainname which is not the internet domainname.
  128. proc domainname {} {
  129.     # open pops stack upon failure
  130.     set rc [catch {open /etc/resolv.conf r} file]
  131.     if {$rc==0} {
  132.     while {-1!=[gets $file buf]} {
  133.         if 1==[scan $buf "domain %s" name] {
  134.         close $file
  135.         return $name
  136.         }
  137.     }
  138.     close $file
  139.     }
  140.  
  141.     # fall back to using domainname
  142.     if {0==[catch {exec domainname} name]} {return $name}
  143.  
  144.     error "could not figure out domainname"
  145. }
  146.  
  147. if $user_number==1 {
  148.     if $noproc==0 {
  149.     if {[llength $argv]>1} {
  150.         set pid [eval spawn [lrange $argv 1 end]]
  151.     } else {
  152.         # if running as CGI, shell may not be set!
  153.         set shell /bin/sh
  154.         catch {set shell $env(SHELL)}
  155.         set pid [spawn $shell]
  156.     }
  157.     set shell $spawn_id
  158.     }
  159.  
  160.     # is user2 remote?
  161.     regexp (\[^@\]*)@*(.*) $user ignore tmp host
  162.     set user $tmp
  163.     if ![string match $host ""] {
  164.     set h_rc [catch {exec hostname}    hostname]
  165.     set d_rc [catch domainname     domainname]
  166.  
  167.     if {![is_prefix $h_rc $host $hostname]
  168.     && ![is_prefix $d_rc $host $hostname.$domainname]} {
  169.         set user2_islocal 0
  170.     }
  171.     }
  172.  
  173.     if !$user2_islocal {
  174.     if $verbose {send_user "connecting to $host\n"}
  175.  
  176.     if ![info exists proxy] {
  177.         proc whoami {} {
  178.         global env
  179.         if {[info exists env(USER)]} {return $env(USER)}
  180.         if {[info exists env(LOGNAME)]} {return $env(LOGNAME)}
  181.         if {![catch {exec whoami} user]} {return $user}
  182.         if {![catch {exec logname} user]} {return $user}
  183.         # error "can't figure out who you are!"
  184.         }
  185.         set proxy [whoami]
  186.     }
  187.     spawn rlogin $host -l $proxy -8
  188.     set userin $spawn_id
  189.     set userout $spawn_id
  190.  
  191.     catch {set prompt $env(EXPECT_PROMPT)}
  192.  
  193.     set timeout 120
  194.     expect {
  195.         assword: {
  196.         stty -echo
  197.         send_user "password (for $proxy) on $host: "
  198.         set old_timeout $timeout; set timeout -1
  199.         expect_user -re "(.*)\n"
  200.         send_user "\n"
  201.         set timeout $old_timeout
  202.         send "$expect_out(1,string)\r"
  203.         # bother resetting echo?
  204.         exp_continue
  205.         } incorrect* {
  206.         send_user "invalid password or account\n"
  207.         exit
  208.         } "TERM = *) " {
  209.         send "\r"
  210.         exp_continue
  211.         } timeout {
  212.         send_user "connection to $host timed out\n"
  213.         exit
  214.         } eof {
  215.         send_user "connection to host failed: $expect_out(buffer)"
  216.         exit
  217.         } -re $prompt
  218.     }
  219.     if {$verbose} {send_user "starting kibitz on $host\n"}
  220.     # the kill protects user1 from receiving user3's
  221.     # prompt if user2 exits via expect's exit.
  222.     send "$kibitz $kibitz_flags -r $user;kill -9 $$\r"
  223.  
  224.     expect {
  225.         -re "kibitz $kibitz_flags -r $user.*KRUN" {}
  226.         -re "kibitz $kibitz_flags -r $user.*(kibitz\[^\r\]*)\r" {
  227.         send_user "unable to start kibitz on $host: \"$expect_out(1,string)\"\n"
  228.         send_user "try rlogin by hand followed by \"kibitz $user\"\n"
  229.         exit
  230.         }
  231.         timeout {
  232.         send_user "unable to start kibitz on $host: "
  233.         set expect_out(buffer) "timed out"
  234.         set timeout 0; expect -re .+
  235.         send_user $expect_out(buffer)
  236.         exit
  237.         }
  238.     }
  239.     expect {
  240.         -re ".*\n" {
  241.         # pass back diagnostics
  242.         # should really strip out extra cr
  243.         send_user $expect_out(buffer)
  244.         exp_continue
  245.         }
  246.         KABORT exit
  247.         default exit
  248.         KDATA
  249.     }
  250.     }
  251. }
  252.  
  253. if {$user_number==2} {
  254.     set pid [string trimleft $user -]
  255. }
  256.  
  257. set local_io [expr ($user_number==3)||$user2_islocal]
  258. if {$local_io||($user_number==2)} {
  259.     if {0==[info exists pid]} {set pid [pid]}
  260.  
  261.     set userinfile /tmp/exp0.$pid
  262.     set useroutfile /tmp/exp1.$pid
  263. }
  264.  
  265. proc prompt1 {} {
  266.     return "kibitz[info level].[history nextid]> "
  267. }
  268.  
  269. set esc_match {}
  270. if {$allow_escape} {
  271.    set esc_match {
  272.       $escape_char {
  273.     send_user "\nto exit kibitz, enter: exit\n"
  274.     send_user "to suspend kibitz, press appropriate job control sequence\n"
  275.     send_user "to return to kibitzing, enter: return\n"
  276.     interpreter
  277.     send_user "returning to kibitz\n"
  278.       }
  279.    }
  280. }
  281.  
  282. proc prompt1 {} {
  283.     return "kibitz[info level].[history nextid]> "
  284. }
  285.  
  286. set timeout -1
  287.  
  288. # kibitzer executes following code
  289. if {$user_number==2} {
  290.     # for readability, swap variables
  291.     set tmp $userinfile
  292.     set userinfile $useroutfile
  293.     set useroutfile $tmp
  294.  
  295.     if ![file readable $userinfile] {
  296.     send_user "Eh?  No one is asking you to kibitz.\n"
  297.     exit -1
  298.     }
  299.     spawn -open [open "|cat $catflags < $userinfile" "r"]
  300.     set userin $spawn_id
  301.  
  302.     spawn -open [open $useroutfile w]
  303.     set userout $spawn_id
  304.     # open will hang until other user's cat starts
  305.  
  306.     stty -echo raw
  307.     if {$allow_escape} {send_user "Escape sequence is $escape_printable\r\n"}
  308.  
  309.     # While user is reading message, try to delete other fifo
  310.     catch {exec rm -f $userinfile}
  311.  
  312.     eval interact $esc_match \
  313.         -output $userout \
  314.         -input $userin
  315.  
  316.     exit
  317. }
  318.  
  319. # only user_numbers 1 and 3 execute remaining code
  320.  
  321. proc abort {} {
  322.     # KABORT tells user_number 1 that user_number 3 has run into problems
  323.     # and is exiting, and diagnostics have been returned already
  324.     if {$::user_number==3} {send_user KABORT}
  325.     exit
  326. }
  327.  
  328. if {$local_io} {
  329.     proc mkfifo {f} {
  330.     if 0==[catch {exec mkfifo $f}] return        ;# POSIX
  331.     if 0==[catch {exec mknod $f p}] return
  332.     # some systems put mknod in wierd places
  333.     if 0==[catch {exec /usr/etc/mknod $f p}] return    ;# Sun
  334.     if 0==[catch {exec /etc/mknod $f p}] return    ;# AIX, Cray
  335.     puts "Couldn't figure out how to make a fifo - where is mknod?"
  336.     abort
  337.     }
  338.  
  339.     proc rmfifos {} {
  340.     global userinfile useroutfile
  341.     catch {exec rm -f $userinfile $useroutfile}
  342.     }
  343.  
  344.     trap {rmfifos; exit} {SIGINT SIGQUIT SIGTERM}
  345.  
  346.     # create 2 fifos to communicate with other user
  347.     mkfifo $userinfile
  348.     mkfifo $useroutfile
  349.     # make sure other user can access despite umask
  350.     exec chmod 666 $userinfile $useroutfile
  351.  
  352.     if {$verbose} {send_user "asking $user to type:  kibitz -$pid\n"}
  353.  
  354.     # can't use exec since write insists on being run from a tty!
  355.     set rc [catch {
  356.            system echo "Can we talk?  Run: \"kibitz -$pid\"" | \
  357.             write $user $tty
  358.         }
  359.     ]
  360.     if {$rc} {rmfifos;abort}
  361.  
  362.     spawn -open [open $useroutfile w]
  363.     set userout $spawn_id
  364.     # open will hang until other user's cat starts
  365.  
  366.     spawn -open [open "|cat $catflags < $userinfile" "r"]
  367.     set userin $spawn_id
  368.     catch {exec rm $userinfile}
  369. }
  370.  
  371. stty -echo raw
  372.  
  373. if {$user_number==3} {
  374.     send_user "KDATA"    ;# this tells user_number 1 to send data
  375.  
  376.     interact {
  377.     -output $userout
  378.     -input $userin eof {
  379.         wait -i $userin
  380.         return -tcl
  381.     } -output $user_spawn_id 
  382.     }
  383. } else {
  384.     if {$allow_escape} {send_user "Escape sequence is $escape_printable\r\n"}
  385.  
  386.     if {$noproc} {
  387.     interact {
  388.         -output $userout
  389.         -input $userin eof {wait -i $userin; return}
  390.         -output $user_spawn_id
  391.     }
  392.     } else {
  393.     eval interact $esc_match {
  394.         -output $shell \
  395.             -input $userin eof {
  396.         wait -i $userin
  397.         close -i $shell
  398.         return
  399.         } -output $shell \
  400.             -input $shell eof {
  401.         close -i $userout
  402.         wait -i $userout
  403.         return
  404.         } -output "$user_spawn_id $userout"
  405.     }
  406.     wait -i $shell
  407.     }
  408. }
  409.  
  410. if {$local_io} rmfifos
  411.